Expand description
This crate provides an alternative API for reading and writing data in an
endianness that might only be known at run-time. It encapsulates the
existing capabilities of the byteorder
crate with an interface that
assumes an implicitly acknowledged byte order.
The benefits of this API is two-fold. This crate supports use cases where the data’s endianness is only known during program execution, which may happen in some formats and protocols. The same API can be used to reduce redundancy by indicating the intended byte order once for the entire routine, instead of once for each method call.
The main contribution in this crate is the ByteOrdered
wrapper type,
which infuses byte order information to a data source or destination (it
works for both readers and writers). Moreover, the Endian
trait
contains multiple primitive data reading and writing methods, and the
Endianness
type provides a basic enumerate for endianness information
only known at run-time.
§Examples
Use one of ByteOrdered
’s constructors to create a wrapper with byte
order awareness.
use byteordered::{ByteOrdered, Endianness};
let mut rd = ByteOrdered::le(get_data_source()?); // little endian
// read a u16
let w = rd.read_u16()?;
// choose to read the following data in Little Endian if it's
// smaller than 256, otherwise read in Big Endian
let mut rd = rd.into_endianness(Endianness::le_iff(w < 256));
let value: u32 = rd.read_u32()?;
Both byteordered
and byteorder
work well side by side. You can use
byteorder
in one part of
the routine, and wrap the reader or writer when deemed useful.
use byteorder::ReadBytesExt;
use byteordered::{ByteOrdered, Endianness};
let b = 5;
// choose to read the following data in Little Endian if it's 0,
// otherwise read in Big Endian (what happens in this case)
let mut wt = ByteOrdered::runtime(
Vec::new(),
if b == 0 { Endianness::Little } else { Endianness::Big }
);
// write in this byte order
wt.write_u16(0xC000)?;
wt.write_u32(0)?;
// then invert the byte order
let mut wt = wt.into_opposite();
wt.write_u16(0xEEFF)?;
assert_eq!(&*wt.into_inner(), &[0xC0, 0, 0, 0, 0, 0, 0xFF, 0xEE]);
As an additional construct, the with_order!
macro is another API for
reading and writing data, with the perk of providing explicit
monomorphization with respect to the given endianness.
with_order!(get_data_source()?, Endianness::Little, |rd| {
let value: u32 = rd.read_u32()?;
println!("-> {}", value);
});
§Features
This library requires the standard library (no_std
is currently not
supported).
Re-exports§
pub extern crate byteorder;
Macros§
- Creates a monomorphized scope for reading or writing with run-time byte order awareness.
Structs§
- Wrapper type for a reader or writer with an assumed byte order.
- A data type representing a byte order known in compile time. Unlike the types provided in
byteorder
, this type can be constructed.
Enums§
- Enumerate for materializing the two kinds of machine byte order supported by Rust in a dynamic fashion. That is, the information of whether to read or write data in Little Endian or in Big Endian is resolved at run time by observing this value.
Traits§
- General trait for types that can serialize and deserialize bytes in some byte order.